package com.ican.action.rule;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ican.common.BusinessException;
import com.ican.common.SystemConstants;
import com.ican.common.hibernate.Page;
import com.ican.domain.product.Category;
import com.ican.domain.product.Language;
import com.ican.domain.rule.CategoryRule;
import com.ican.domain.rule.ParseRule;
import com.ican.domain.rule.WebsiteRule;
import com.ican.nc.RuleCategoryScan;
import com.ican.nc.ParseRuleVo;
import com.ican.nc.ParseUtil;
import com.ican.service.product.ProductService;
import com.ican.service.rule.RuleConfigService;
import com.ican.util.ContextUtils;
import com.opensymphony.xwork2.ActionSupport;

public class RuleAction extends ActionSupport {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LoggerFactory.getLogger(RuleAction.class);
    
    private RuleConfigService ruleConfigService;

    private List<Language> langs;
    
    //站点相关
    private WebsiteRule website;
    private List<WebsiteRule> websiteList;
    private Page<WebsiteRule> websitePage = new Page<WebsiteRule>();
    public String toAddWebsite() {
        return "addwebsite";
    }
    public String addWebsite() {
        try{
            website.setId(null);
            ruleConfigService.addWebsite(website);
            ContextUtils.successMsg2Session(null);
            return websiteList();
        }catch(BusinessException e){
            ContextUtils.errorMsg2Session(e.getMessage());
            logger.error(e.getMessage(),e);
        }catch(Exception e){
            ContextUtils.errorMsg2Session(null);
            logger.error(e.getMessage(),e);
        }
        return "addwebsite";
    }
    public String toEditWebsite() {
        website = ruleConfigService.findWebsite(website.getId());
        return "editwebsite";
    }
    public String editWebsite() {
        try{
            ruleConfigService.modifyWebsite(website);
            ContextUtils.successMsg2Session(null);
            return websiteList();
        }catch(BusinessException e){
            ContextUtils.errorMsg2Session(e.getMessage());
            logger.error(e.getMessage(),e);
        }catch(Exception e){
            ContextUtils.errorMsg2Session(null);
            logger.error(e.getMessage(),e);
        }
        return "editwebsite";
    }
    public String websiteList() {
        websitePage = ruleConfigService.findWebsite(websitePage, website);
        return "listwebsite";
    }
    public String ajaxWebsite() {
        websiteList = ruleConfigService.findWebsite(website);
        return "ajaxwebsite";
    }
    
    //类目相关
    private CategoryRule category;
    private Page<CategoryRule> categoryPage = new Page<CategoryRule>();
    public String toAddCategory() {
        langs = ruleConfigService.findLanguage();
        ruleList = ruleConfigService.findAllRule(category.getWebsiteId(), SystemConstants.ENTITY_DATE_STATUS_YES);
        return "addcategory";
    }
    public String addCategory() {
        try{
            if(category.getCode() == null || category.getCode().trim().length() < 1 || ruleConfigService.categoryCodeIsExist(category.getCode())){
                ContextUtils.errorMsg2Session("类目编码为空或者已经存在。");
                return websiteList();
            }
            category.setId(null);
            ruleConfigService.addCategory(category);
            ContextUtils.successMsg2Session(null);
            return websiteList();
        }catch(BusinessException e){
            ContextUtils.errorMsg2Session(e.getMessage());
            logger.error(e.getMessage(),e);
        }catch(Exception e){
            ContextUtils.errorMsg2Session(null);
            logger.error(e.getMessage(),e);
        }
        return toAddCategory();
    }
    public String toEditCategory() {
        category = ruleConfigService.findCategory(category.getId());
        langs = ruleConfigService.findLanguage();
        ruleList = ruleConfigService.findAllRule(category.getWebsiteId(), SystemConstants.ENTITY_DATE_STATUS_YES);
        return "editcategory";
    }
    public String editCategory() {
        try{
            ruleConfigService.modifyCategory(category);
            ContextUtils.successMsg2Session(null);
            return categoryList();
        }catch(BusinessException e){
            ContextUtils.errorMsg2Session(e.getMessage());
            logger.error(e.getMessage(),e);
        }catch(Exception e){
            ContextUtils.errorMsg2Session(null);
            logger.error(e.getMessage(),e);
        }
        langs = ruleConfigService.findLanguage();
        ruleList = ruleConfigService.findAllRule(category.getWebsiteId(), SystemConstants.ENTITY_DATE_STATUS_YES);
        return "editcategory";
    }
    public String categoryList() {
        categoryPage = ruleConfigService.findCategory(categoryPage, category);
        return "listcategory";
    }
    
    //规则相关
    private ParseRuleVo ruleVo;
    private List<ParseRule> ruleList;
    public String toAddRule() {
        if(website != null || website.getId() != null){
            website = ruleConfigService.findWebsite(website.getId());
        }else if(ruleVo != null || ruleVo.getWebsiteId() != null){
            website = ruleConfigService.findWebsite(ruleVo.getWebsiteId());
        }
        return "addrule";
    }
    public String addRule() {
        try{
            ParseRule rule = new ParseRule();
            ParseUtil.ruleVo2Rule(ruleVo, rule);
            rule.setId(null);
            ruleConfigService.addRule(rule);
            ContextUtils.successMsg2Session(null);
            return websiteList();
        }catch(BusinessException e){
            ContextUtils.errorMsg2Session(e.getMessage());
            logger.error(e.getMessage(),e);
        }catch(Exception e){
            ContextUtils.errorMsg2Session(null);
            logger.error(e.getMessage(),e);
        }
        return toAddRule();
    }
    public String toEditRule() {
        ParseRule rule = ruleConfigService.findRule(ruleVo.getId());
        ParseUtil.rule2RuleVo(rule, ruleVo);
        website = ruleConfigService.findWebsite(ruleVo.getWebsiteId());
        return "editrule";
    }
    public String editRule() {
        try{
            ParseRule rule = new ParseRule();
            ParseUtil.ruleVo2Rule(ruleVo, rule);
            ruleConfigService.modifyRule(rule);
            ContextUtils.successMsg2Session(null);
            return websiteList();
        }catch(BusinessException e){
            ContextUtils.errorMsg2Session(e.getMessage());
            logger.error(e.getMessage(),e);
        }catch(Exception e){
            ContextUtils.errorMsg2Session(null);
            logger.error(e.getMessage(),e);
        }
        website = ruleConfigService.findWebsite(ruleVo.getWebsiteId());
        return "editrule";
    }
    public String ruleList() {
        ruleList = ruleConfigService.findAllRule(ruleVo.getWebsiteId(), SystemConstants.ENTITY_DATE_STATUS_YES);
        return "listrule";
    }
    
    //运行相关
    private ProductService productService;
    private RuleCategoryScan ruleCategoryScan;
    private Integer scanType;
    public String startJobWebsite() {
        CategoryRule cr = new CategoryRule();
        cr.setWebsiteId(website.getId());
        cr.setDataStatus(SystemConstants.ENTITY_DATE_STATUS_YES);
        List<Integer> cIds = ruleConfigService.findAllCategoryIdToScan(cr);
        StringBuffer sb = new StringBuffer();
        if(cIds != null && cIds.size() > 0){
            for(Integer cid : cIds){
                try{
                    if(startJob(cid)){
                        
                    }else{
                        sb.append(",");
                        sb.append(cid);
                    }
                }catch(Exception e){
                    sb.append(",");
                    sb.append(cid);
                    ContextUtils.errorMsg2Session(e.getMessage());
                    logger.error(e.getMessage(),e);
                }
            }
        }
        if(sb.length() > 1){
            ContextUtils.errorMsg2Session("类目" + sb.delete(0, 1).toString() + "的扫描不能正常启动，请检查！");
        }else{
            ContextUtils.successMsg2Session("扫描已经完成。");
        }
        return websiteList();
    }
    public String startJobCategory() {
        try{
            if(startJob(category.getId())){
                ContextUtils.successMsg2Session("扫描已经正常启动。");
            }else{
                ContextUtils.errorMsg2Session("扫描不能正常启动，请检查！");
            }
        }catch(Exception e){
            ContextUtils.errorMsg2Session(e.getMessage());
            logger.error(e.getMessage(),e);
        }
        return categoryList();
    }
    private boolean startJob(Integer cid) {
        CategoryRule cr = ruleConfigService.findCategory(cid);
        //是否可用
        if(cr.getDataStatus() == SystemConstants.ENTITY_DATE_STATUS_NO){
            return false;
        }
        //是否在扫描
        if(cr.getScanStatus() != null && cr.getScanStatus() == SystemConstants.RULE_CONFIG_SCAN_STATUS_RUN){
            return false;
        }
        //查询规则
        ParseRule pr = ruleConfigService.findRule(cr.getRuleId());
        if(pr == null){
            return false;
        }
        //生成商品类目
        Category pc = new Category();
        pc.setName(cr.getName());
        pc.setCode(cr.getCode());
        pc.setDescription(cr.getDescription());
        pc.setLangId(cr.getLangId());
        pc.setUrl(cr.getUrl());
        pc.setRuleId(cr.getRuleId());
        productService.addCategory(pc);
        //处理规则
        ParseRuleVo vo = new ParseRuleVo();
        vo.setCateCode(pc.getCode());
        ParseUtil.rule2RuleVo(pr, vo);
        vo.setRuleCateId(cr.getId());
        vo.setProCateId(pc.getId());
        vo.setLangId(cr.getLangId());
        //开始扫描
        if(scanType != null && scanType == SystemConstants.RULE_CONFIG_SCAN_STATUS_FAILED){//错误扫描
            if(cr.getScanStatus() != null && cr.getScanStatus() == SystemConstants.RULE_CONFIG_SCAN_STATUS_FAILED && 
                    cr.getLastPageUrl() != null){
                ruleConfigService.updateCategoryScanStatus(cr.getId(), SystemConstants.RULE_CONFIG_SCAN_STATUS_RUN);
                ruleCategoryScan.scanCategory(vo, cr.getLastPageUrl());
            }
        }else{
            ruleConfigService.updateCategoryScanStatus(cr.getId(), SystemConstants.RULE_CONFIG_SCAN_STATUS_RUN);
            ruleCategoryScan.scanCategory(vo, cr.getUrl());
        }
        return true;
    }
    
    @Resource
    public void setRuleCategoryScan(RuleCategoryScan ruleCategoryScan) {
        this.ruleCategoryScan = ruleCategoryScan;
    }
    @Resource
    public void setRuleConfigService(RuleConfigService ruleConfigService) {
        this.ruleConfigService = ruleConfigService;
    }
    @Resource
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }
    public WebsiteRule getWebsite() {
        return website;
    }
    public void setWebsite(WebsiteRule website) {
        this.website = website;
    }
    public Page<WebsiteRule> getWebsitePage() {
        return websitePage;
    }
    public void setWebsitePage(Page<WebsiteRule> websitePage) {
        this.websitePage = websitePage;
    }
    public CategoryRule getCategory() {
        return category;
    }
    public void setCategory(CategoryRule category) {
        this.category = category;
    }
    public Page<CategoryRule> getCategoryPage() {
        return categoryPage;
    }
    public void setCategoryPage(Page<CategoryRule> categoryPage) {
        this.categoryPage = categoryPage;
    }
    public ParseRuleVo getRuleVo() {
        return ruleVo;
    }
    public void setRuleVo(ParseRuleVo ruleVo) {
        this.ruleVo = ruleVo;
    }
    public List<ParseRule> getRuleList() {
        return ruleList;
    }
    public void setRuleList(List<ParseRule> ruleList) {
        this.ruleList = ruleList;
    }
    public List<Language> getLangs() {
        return langs;
    }
    public void setLangs(List<Language> langs) {
        this.langs = langs;
    }
    public List<WebsiteRule> getWebsiteList() {
        return websiteList;
    }
    public void setWebsiteList(List<WebsiteRule> websiteList) {
        this.websiteList = websiteList;
    }
    public Integer getScanType() {
        return scanType;
    }
    public void setScanType(Integer scanType) {
        this.scanType = scanType;
    }
}
